%{
#include <cstdlib>
#include <errno.h>
#include <limits.h>
#include <string>
#include "slak/mesh/SG3.h"
#include "slak/mesh/ResourceParserDriver.h"
#include "slak/mesh/ResourceParser.hh"
     
     /* Work around an incompatibility in flex (at least versions
        2.5.31 through 2.5.33): it generates code that does
        not conform to C89.  See Debian bug 333231
        <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.  */
#undef yywrap
#define yywrap() 1
     
     /* By default yylex returns int, we use token_type.
        Unfortunately yyterminate by default returns 0, which is
        not of token_type.  */
#define yyterminate() return token::END

typedef yy::parser::token token;
typedef yy::parser::token_type token_type;

%}

%option noyywrap nounput batch debug

literal		"["|"]"
endl		"\n"
comment 	";".*
alpha		[A-Za-z]
digit		[0-9]
alnum		{alpha}|{digit}
_alpha		_|{alpha}
_alnum		{_alpha}|{digit}
keyword		{_alpha}{_alnum}*
integer		{digit}+
real		{digit}*\.{digit}+|{digit}+\.{digit}*
number		{integer}|{real}
blank		[ \t]
string		\"[^\"]*\"
blank_line	^{blank}*{comment}?{endl}

%{
#define YY_USER_ACTION  yylloc->columns (yyleng);
%}
%%
%{
yylloc->step ();
%}
	/* eat spaces */
{blank}+	yylloc->step();
	/* eat each blank line separatelly for line counting */
{blank_line}	yylloc->lines(1); yylloc->step();


{literal}	return token_type(yytext[0]);

{keyword}	{ 
	yylval->arg = new yy::Arg();
	*(yylval->arg) = std::string(yytext);
	return token::KEYWORD; 
}

{number}	{ 
	errno = 0;
	double res = strtod(yytext, NULL);
	if (errno == ERANGE)
		driver.error(*yylloc, "number out of range");
	yylval->arg = new yy::Arg();
	*(yylval->arg) = res;
	return token::NUMBER; 
}

{string}	{ 
	yylval->arg = new yy::Arg();
	*(yylval->arg) = std::string(yytext,1,yyleng-2);
	return token::STRING; 
}

	/* inline comment (full line comments are eaten above */
{comment}	yylloc->step();
	/* meaningfull line end */
{endl} 		yylloc->lines(1); return token_type('\n');
	/* garbage: curse */
.		driver.error(*yylloc, "invalid character");
%%

void
yy::parser_driver::scan_begin()
{
	yy_flex_debug = trace_scanning;
	if (!(yyin = fopen (file.c_str (), "r")))
		error (std::string ("cannot open ") + file);
}
     
void
yy::parser_driver::scan_end()
{
	fclose(yyin);
}

 
